#!/usr/bin/env python3
"""
插件系统测试运行器

运行插件系统的所有单元测试，并生成测试报告。
"""

import sys
import subprocess
import argparse
from pathlib import Path


def run_tests(test_pattern=None, verbose=False, coverage=False, html_report=False):
    """运行插件系统测试"""
    
    # 基本pytest命令
    cmd = ["python", "-m", "pytest"]
    
    # 测试文件模式
    if test_pattern:
        cmd.append(test_pattern)
    else:
        # 运行所有插件相关测试
        cmd.extend([
            "test_plugin_base.py",
            "test_plugin_exceptions.py", 
            "test_plugin_manager.py",
            "test_plugin_loader.py",
            "test_plugin_registry.py",
            "test_plugin_hooks.py",
            "test_plugin_context.py",
            "test_plugin_integration.py"
        ])
    
    # 详细输出
    if verbose:
        cmd.append("-v")
    
    # 覆盖率测试
    if coverage:
        cmd.extend([
            "--cov=src.core.plugin",
            "--cov-report=term-missing"
        ])
        
        if html_report:
            cmd.append("--cov-report=html:htmlcov")
    
    # 其他有用的选项
    cmd.extend([
        "--tb=short",  # 简短的traceback
        "--strict-markers",  # 严格的标记检查
        "-ra",  # 显示所有测试结果摘要
    ])
    
    print(f"运行命令: {' '.join(cmd)}")
    print("=" * 60)
    
    # 运行测试
    result = subprocess.run(cmd, cwd=Path(__file__).parent)
    return result.returncode


def run_specific_test_class(test_file, test_class=None, test_method=None):
    """运行特定的测试类或方法"""
    
    cmd = ["python", "-m", "pytest", "-v"]
    
    if test_class and test_method:
        test_target = f"{test_file}::{test_class}::{test_method}"
    elif test_class:
        test_target = f"{test_file}::{test_class}"
    else:
        test_target = test_file
    
    cmd.append(test_target)
    
    print(f"运行特定测试: {test_target}")
    print("=" * 60)
    
    result = subprocess.run(cmd, cwd=Path(__file__).parent)
    return result.returncode


def run_performance_tests():
    """运行性能测试"""
    
    cmd = [
        "python", "-m", "pytest", "-v",
        "-m", "performance",  # 只运行标记为performance的测试
        "--benchmark-only",   # 只运行基准测试
        "--benchmark-sort=mean"  # 按平均时间排序
    ]
    
    print("运行性能测试...")
    print("=" * 60)
    
    result = subprocess.run(cmd, cwd=Path(__file__).parent)
    return result.returncode


def run_integration_tests():
    """运行集成测试"""
    
    cmd = [
        "python", "-m", "pytest", "-v",
        "test_plugin_integration.py",
        "--tb=long"  # 详细的traceback用于调试
    ]
    
    print("运行集成测试...")
    print("=" * 60)
    
    result = subprocess.run(cmd, cwd=Path(__file__).parent)
    return result.returncode


def generate_test_report():
    """生成测试报告"""
    
    cmd = [
        "python", "-m", "pytest",
        "--html=reports/plugin_test_report.html",
        "--self-contained-html",
        "--cov=src.core.plugin",
        "--cov-report=html:reports/coverage",
        "--cov-report=xml:reports/coverage.xml",
        "--junit-xml=reports/junit.xml"
    ]
    
    # 创建报告目录
    reports_dir = Path(__file__).parent / "reports"
    reports_dir.mkdir(exist_ok=True)
    
    print("生成测试报告...")
    print("=" * 60)
    
    result = subprocess.run(cmd, cwd=Path(__file__).parent)
    
    if result.returncode == 0:
        print("\n测试报告生成成功:")
        print(f"  HTML报告: {reports_dir / 'plugin_test_report.html'}")
        print(f"  覆盖率报告: {reports_dir / 'coverage' / 'index.html'}")
        print(f"  JUnit XML: {reports_dir / 'junit.xml'}")
    
    return result.returncode


def check_test_dependencies():
    """检查测试依赖"""
    
    required_packages = [
        "pytest",
        "pytest-cov", 
        "pytest-html",
        "pytest-asyncio",
        "pytest-mock"
    ]
    
    missing_packages = []
    
    for package in required_packages:
        try:
            __import__(package.replace("-", "_"))
        except ImportError:
            missing_packages.append(package)
    
    if missing_packages:
        print("缺少以下测试依赖:")
        for package in missing_packages:
            print(f"  - {package}")
        print("\n请运行以下命令安装:")
        print(f"pip install {' '.join(missing_packages)}")
        return False
    
    return True


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description="插件系统测试运行器")
    
    parser.add_argument(
        "--pattern", "-p",
        help="测试文件模式"
    )
    
    parser.add_argument(
        "--verbose", "-v",
        action="store_true",
        help="详细输出"
    )
    
    parser.add_argument(
        "--coverage", "-c",
        action="store_true",
        help="运行覆盖率测试"
    )
    
    parser.add_argument(
        "--html-report",
        action="store_true",
        help="生成HTML覆盖率报告"
    )
    
    parser.add_argument(
        "--class", "-C",
        dest="test_class",
        help="运行特定测试类"
    )
    
    parser.add_argument(
        "--method", "-m",
        dest="test_method",
        help="运行特定测试方法"
    )
    
    parser.add_argument(
        "--file", "-f",
        dest="test_file",
        help="运行特定测试文件"
    )
    
    parser.add_argument(
        "--performance",
        action="store_true",
        help="运行性能测试"
    )
    
    parser.add_argument(
        "--integration",
        action="store_true",
        help="运行集成测试"
    )
    
    parser.add_argument(
        "--report",
        action="store_true",
        help="生成完整测试报告"
    )
    
    parser.add_argument(
        "--check-deps",
        action="store_true",
        help="检查测试依赖"
    )
    
    args = parser.parse_args()
    
    # 检查依赖
    if args.check_deps:
        if check_test_dependencies():
            print("所有测试依赖都已安装")
            return 0
        else:
            return 1
    
    # 检查测试依赖
    if not check_test_dependencies():
        return 1
    
    # 运行特定测试
    if args.test_file or args.test_class or args.test_method:
        test_file = args.test_file or "test_plugin_base.py"
        return run_specific_test_class(test_file, args.test_class, args.test_method)
    
    # 运行性能测试
    if args.performance:
        return run_performance_tests()
    
    # 运行集成测试
    if args.integration:
        return run_integration_tests()
    
    # 生成报告
    if args.report:
        return generate_test_report()
    
    # 运行常规测试
    return run_tests(
        test_pattern=args.pattern,
        verbose=args.verbose,
        coverage=args.coverage,
        html_report=args.html_report
    )


if __name__ == "__main__":
    exit_code = main()
    sys.exit(exit_code)
